#ifndef NODE_H
#define NODE_H
#include <stdint.h>
#include "table.h"
typedef enum
{
    NODE_INTERNAL, // 内部节点
    NODE_LEAF      // 叶节点
} NodeType;

// 常量数据
extern const uint32_t NODE_TYPE_SIZE;
extern const uint32_t NODE_TYPE_OFFSET;
extern const uint32_t IS_ROOT_SIZE;
extern const uint32_t IS_ROOT_OFFSET;
extern const uint32_t PARENT_POINTER_SIZE;
extern const uint32_t PARENT_POINTER_OFFSET;
extern const uint8_t COMMON_NODE_HEADER_SIZE;

// 叶节点格式
extern const uint32_t LEAF_NODE_NUM_CELLS_SIZE;
extern const uint32_t LEAF_NODE_NUM_CELLS_OFFSET;
extern const uint32_t LEAF_NODE_HEADER_SIZE;
extern const uint32_t LEAF_NODE_NEXT_LEAF_OFFSET;
// 叶节点格式布局
extern const uint32_t LEAF_NODE_KEY_SIZE;
extern const uint32_t LEAF_NODE_KEY_OFFSET;
extern const uint32_t LEAF_NODE_VALUE_SIZE;
extern const uint32_t LEAF_NODE_VALUE_OFFSET;
extern const uint32_t LEAF_NODE_CELL_SIZE;
extern const uint32_t LEAF_NODE_SPACE_FOR_CELLS;
extern const uint32_t LEAF_NODE_MAX_CELLS;

// 分裂后，右节点孩子的数量
extern const uint32_t LEAF_NODE_RIGHT_SPLIT_COUNT;
// 分列后，左节点孩子数量
extern const uint32_t LEAF_NODE_LEFT_SPLIT_COUNT;

void initialize_leaf_node(Node *node);
void initialize_internal_node(Internal_Node *node);

// 返回table的根节点

void *get_table_root(Table *table);

// 二分查找key在table 第page_num的值，叶节点
Cursor *leaf_node_find(Table *table, uint32_t page_num, uint32_t key);
// 二分查找，内部节点
Cursor *internal_node_find(Table *table, uint32_t page_num, uint32_t key);
// 插入一行, 在叶子节点满了的时候，叶节点
void leaf_node_insert(Cursor *cursor, uint32_t key, Row *value);
// 插入一行，在叶子节点满了的时候，叶节点
void leaf_node_split_and_insert(Cursor *cursor, uint32_t key, Row *value);
// 插入一行，在内部节点没有满了的时候，内部节点
void internal_node_insert(Table *table, uint32_t parent_page_num, uint32_t child_page_num);
// 插入一行，在内部节点满了的时候，内部节点
void internal_node_split_and_insert(Table *table, uint32_t parent_page_num, uint32_t child_page_num);
// 创建一个新的根节点
void create_new_root(Table *table, uint32_t right_child_page_num);

// 更新节点在父节点上最大的key
void update_internal_node_key(Table *table, uint32_t parent_num, uint32_t child_num);
// 获取节点的类型
NodeType get_node_type(void *node);
// 获取节点最大的key，用于标记索引
uint32_t get_node_max_key(void *node);
#endif